// Box<T>
//常用的场景
//1. 在编译时，某些类型的大小无法确定， 但是使用该类型时候，上下文需要知道这个类型的确切大小
//2. 当你有大量的数据，想移交所有权， 但是需要 确保在操作时数据不会被复制
//3.使用某个值，只关心是否实现了某个Trait，不关心的的具体类型


#[test]
fn test1() {
    let a = Box::new(33);
    println!("a is {}", a);
}


use std::ops::Deref;
use crate::test_box::List::{Cons, Nil};

#[test]
fn test2() {

    // Box  实现类似链表的功能
    // Box  就是一个指针
    //Rust  需要知道数据结构的大小，
    let list = Cons(1,
                    Box::new(Cons(2,
                                  Box::new(Cons(3,
                                                Box::new(Nil))))));
    println!("list is {:?}", list);
}


#[derive(Debug)]
enum List {
    Cons(i32, Box<List>),
    Nil,
}


#[test]
fn test3() {
    let x = 5;
    let y = &x; //   y 是指针

    assert_eq!(5, x);
    // assert_eq!(5, y);

    assert_eq!(5, *y);  // *y  是取出 指针指向的值
    // assert_eq!(5, y) ;  // 会报错  no implementation for `{integer} == &{integer}`
    println!("y is {:?}", *y);


    //用Box  改造上面的例子


    let x = 5;
    let y = Box::new(x);

    assert_eq!(5, x);


    assert_eq!(5, *y);  // *y  是取出 指针指向的值
    println!("y is {:?}", *y);


    // 用 MyBox 改造上面的例子

    let x = 5;
    let y = MyBox::new(x);

    assert_eq!(5, x);
    assert_eq!(5, *y);  // *y  是取出 指针指向的值   *y 等价于 *(y.deref())
    println!("y is {:?}", *y);
}

// 元组结构体
struct MyBox<T>(T);

impl<T> MyBox<T> {
    fn new(x: T) -> MyBox<T> {
        MyBox(x)
    }
}

// 结构体实现了 Deref 这个trait ， 就可以使用解引用，否则会报错
impl<T> Deref for MyBox<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}